#include <tinx/debug.h>
#include <tinx/cpu.h>
#include <tinx/assert.h>
#include <tinx/types.h>

static u32 get_eflags()
{
    asm volatile(
        "pushfl\n"
        "popl %eax\n");
}

static void set_eflags(u32 eflags)
{
    asm volatile(
        "pushl %%eax\n"
        "popfl\n" :: "a"(eflags));

}

// 得到供应商 ID 字符串
void cpu_vendor_id(cpu_vendor_t *item)
{
    asm volatile(
        "cpuid \n"
        : "=a"(*((u32 *)item + 0)),
          "=b"(*((u32 *)item + 1)),
          "=d"(*((u32 *)item + 2)),
          "=c"(*((u32 *)item + 3))
        : "a"(0));
    item->info[12] = 0;
}

void cpu_version(cpu_version_t *item)
{
    asm volatile(
        "cpuid \n"
        : "=a"(*((u32 *)item + 0)),
          "=b"(*((u32 *)item + 1)),
          "=c"(*((u32 *)item + 2)),
          "=d"(*((u32 *)item + 3))
        : "a"(1));
}

bool cpu_check_cpuid()
{
    u32 eflags = get_eflags();
    assert((eflags & 0x200000) == 0);

    eflags |= 0x200000;
    set_eflags(eflags);

    eflags = get_eflags();
    return eflags & 0x200000;
}